package com.sunfeng.gulimall.product.listener;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.concurrent.CountDownLatch;

/**
 * @Author : 清风冷影
 * @Description: redis消息队列配置-订阅者
 * @Date : 2021/11/14  20:48
 */
@Slf4j
@Configuration
public class RedisMessageListener {

    ThreadPoolTaskScheduler taskScheduler;

    /**
     * 创建连接容器
     * @param connectionFactory   链接工厂在spring容器中已经存在 如果是自己配置spring data与redis整合是需要自己配置连接工厂，但是spring boot已经帮我们配置好了，所以可以直接注入。
     * @param listenerAdapter   使用消息监听适配器  这里我创建了两个 分别监听两个通道
     * @return
     */
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                                   MessageListenerAdapter listenerAdapter, MessageListenerAdapter listenerAdapter2) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setTaskExecutor(redisTaskScheduler());
        //接受消息的key
        container.addMessageListener(listenerAdapter, new PatternTopic("channel:message1"));
        container.addMessageListener(listenerAdapter2, new PatternTopic("channel:message2"));
        return container;
    }
    /**
     * 绑定消息监听者和接收监听的方法
     * @param receiver
     * @return
     */
    @Bean
    public MessageListenerAdapter listenerAdapter(ReceiverRedisMessage  receiver){
        // 这里对应ReceiverRedisMessage的方法  内部使用了反射机制完成的  具体内容以后分析
        return new MessageListenerAdapter(receiver,"receiveMessage1");
    }
    /**
     * 绑定消息监听者和接收监听的方法
     * @param receiver
     * @return
     */
    @Bean
    public MessageListenerAdapter listenerAdapter2(ReceiverRedisMessage  receiver){
        return new MessageListenerAdapter(receiver,"receiveMessage2");
    }
    /**
     * 注册订阅者
     * @param latch
     * @return
     */
    @Bean
    ReceiverRedisMessage receiver(CountDownLatch latch) {
        return new ReceiverRedisMessage(latch);
    }


    /**
     * 计数器，用来控制线程
     * @return
     */
    @Bean
    public CountDownLatch latch(){
        return new CountDownLatch(1);//指定了计数的次数 1
    }
    /**
     * 非常关键不添加线程一直往上累加 不销毁
     * @return
     */
    @Bean
    public ThreadPoolTaskScheduler redisTaskScheduler(){
        if(taskScheduler != null){
            return taskScheduler;
        }
        log.info("初始化线程池");
        taskScheduler = new ThreadPoolTaskScheduler();
        //设置线程数
        taskScheduler.setPoolSize(10);
        return taskScheduler;
    }

}
